package com.uye.framework.command;

import java.io.IOException;

import javax.servlet.http.HttpServletResponse;

import net.sf.json.JSONObject;

import org.apache.log4j.Logger;

import com.uye.framework.dto.ErrorJSONResponse;
import com.uye.framework.dto.IJSONResponse;
import com.uye.framework.dto.VerboseErrorJSONResponse;
import com.uye.framework.exception.CommandNotReadyForExecutionException;
import com.uye.framework.exception.InternalServerException;
import com.uye.framework.util.StringUtils;

public class ReturnErrorCommand extends
		BaseStatefulCommand<InternalServerException> {

	Logger logger = Logger.getLogger(this.getClass());

	private HttpServletResponse httpServletResponse;
	private boolean verbosity = false;

	@Override
	public void undo() {
	}

	public InternalServerException getCaughtException() {
		return getModel();
	}

	public void initialize(HttpServletResponse httpServletResponse,
			InternalServerException caughtException) {
		this.httpServletResponse = httpServletResponse;
		setModel(caughtException);
	}

	@Override
	public void checkReadyForExecution()
			throws CommandNotReadyForExecutionException {
		super.checkReadyForExecution();
		String message = null;
		if (null == getModel()) {
			message = "A required field 'caughtException' has not been set.";
		} else if (null == httpServletResponse) {
			message = "A required field "
					+ "'httpServletResponse' has not been set.";
		}

		if (message != null) {
			throw new CommandNotReadyForExecutionException(message);
		}
	}

	@Override
	public void executeCommand() throws InternalServerException {

		ErrorJSONResponse response;
		if (isVerbose()) {
			response = new VerboseErrorJSONResponse(getCaughtException()
					.getServiceName(), getCaughtException().getErrorCode(),
					getCaughtException().getErrorDescription(),
					StringUtils.toString(getCaughtException()));
		} else {
			response = new ErrorJSONResponse(getCaughtException()
					.getServiceName(), getCaughtException().getErrorCode(),
					getCaughtException().getErrorDescription());
		}
		reportError(response);

		logger.error(StringUtils.toString(getModel()));

	}

	public void setVerbose(boolean verbosity) {
		this.verbosity = verbosity;
	}

	public boolean isVerbose() {
		return verbosity;
	}

	public void reportError(IJSONResponse response)
			throws InternalServerException {
		JSONObject json = JSONObject.fromObject(response);
		try {
			json.write(httpServletResponse.getWriter());
		} catch (IOException e) {
			throw new InternalServerException(getModel().getServiceName(),
					"Could not send the response to the client.", e);
		}
	}
}
